package com.ep.thirdPlatformProject.erp.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ep.thirdPlatformProject.erp.config.ErpConfig;
import com.ep.thirdPlatformProject.erp.entity.ErpCommonExecution;
import com.ep.thirdPlatformProject.erp.entity.budget.ErpBudgetDetailEntity;
import com.ep.thirdPlatformProject.erp.entity.budget.ErpBudgetItemEntity;
import com.ep.thirdPlatformProject.erp.entity.budget.ErpBudgetMainEntity;
import com.ep.thirdPlatformProject.erp.entity.dto.ErpBudgetDto;
import com.ep.thirdPlatformProject.erp.entity.vo.ErpBudgetResultVo;
import com.ep.thirdPlatformProject.erp.helper.ErpCommonHelper;
import com.ep.thirdPlatformProject.erp.mapper.ErpBudgetDetailMapper;
import com.ep.thirdPlatformProject.erp.mapper.ErpBudgetMainMapper;
import com.ep.thirdPlatformProject.erp.service.ErpBudgetService;
import com.ep.thirdPlatformProject.system.util.WebclientUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
@RequiredArgsConstructor
public class ErpBudgetServiceImpl extends ServiceImpl<ErpBudgetMainMapper, ErpBudgetMainEntity> implements ErpBudgetService {

    private final ErpBudgetMainMapper mainMapper;

    private final ErpBudgetDetailMapper detailMapper;

    private final ThreadPoolTaskExecutor executor;

    private final ErpCommonHelper erpCommonHelper;

    private final WebclientUtil webclientUtil;

    private final ErpConfig erpConfig;

    /**
     * 获取所有列表数据
     *
     * @return {@link List }<{@link ErpBudgetMainEntity }>
     */
    @Override
    public List<ErpBudgetResultVo> getAllListData(MPJLambdaWrapper<ErpBudgetMainEntity> queryWrapper) {
        try {
            // 切换为自由组合装类
            List<ErpBudgetResultVo> list = mainMapper.selectJoinList(ErpBudgetResultVo.class, queryWrapper);
            List<String> billNoList = list.stream().map(ErpBudgetResultVo::getBillNo).toList();
            if (billNoList.isEmpty()) {
                return new ArrayList<>();
            }
            List<ErpBudgetDetailEntity> budgetDetailList = this.getBudgetDetailList(billNoList);

            List<CompletableFuture<ErpBudgetResultVo>> futureList = list.stream().parallel().map(main ->
                    CompletableFuture.supplyAsync(() -> {
                        main.setDetailList(new ArrayList<>());
                        budgetDetailList.forEach(item -> {
                            if (item.getEnterpriseId().equals(main.getEnterpriseId())
                                    && item.getBillNo().equals(main.getBillNo())) {
                                List<ErpBudgetDetailEntity> detailList = main.getDetailList();
                                if (detailList == null || detailList.isEmpty()) {
                                    detailList = new ArrayList<>();
                                }
//                                item.setPeriodsUsageRate(item.getPeriodsUsageRate() / 100);
                                detailList.add(item);
                                main.setDetailList(detailList);
                            }
                        });
                        return main;
                    }, executor)).toList();
            return futureList.stream().map(CompletableFuture::join).toList();
        } catch (Exception e) {

            throw new RuntimeException("获取所有的预算申请单并且发送数据失败了！", e);
        }

    }

    /**
     * 获取所有列表数据
     *
     * @param deptIds 部门id
     * @return {@link List }<{@link ErpBudgetResultVo }>
     */
    @Override
    public List<ErpBudgetResultVo> getAllListData(String[] deptIds) {
        try {
            List<ErpBudgetResultVo> resultVos = mainMapper.selectDefaultList(deptIds);
            log.info("deptIds:{}", Arrays.asList(deptIds));
            return resultVos;
        } catch (Exception e) {
            throw new RuntimeException("获取所有的预算申请单并且发送数据失败了！", e);
        }
    }

    /**
     * 上传至erp并更改状态
     *
     * @param vo 对象vo
     * @return {@link String }
     */
    @Override
    public String postToErpAndChangeStatus(ErpBudgetResultVo vo) {
        StringBuilder message = new StringBuilder();
        try {
            ErpBudgetDto dto = new ErpBudgetDto();
            dto.setBillNo(vo.getBillNo());
            dto.setStatus("W");
            dto.setVersionId("1");
            List<ErpBudgetDto> paramList = Collections.singletonList(dto);
            if (ObjectUtil.isNull(vo)) {
                return "当前需要推送erp的数据为空！无需下推";
            }
            Map<String, Object> map = new HashMap<>();
            map.put("list", paramList);
            // 此处使用的json序列化方式
            String param = erpCommonHelper.buildPayload(map, "update_cbgt003");

            String response = webclientUtil.post(erpConfig.getUrl(), param, String.class);

            ErpCommonExecution execution = erpCommonHelper.parseResponseToRes(response);
            String description = execution.getDescription();

            message.append("下推erp结果:").append(description);
        } catch (Exception e) {
            return StrUtil.format("下推时失败了，原因是{}", e.getMessage());
        }

        return message.toString();
    }

    /**
     * 获取预算明细列表
     *
     * @param billNoList 账单没有清单
     * @return {@link List }<{@link ErpBudgetDetailEntity }>
     */
    private List<ErpBudgetDetailEntity> getBudgetDetailList(List<String> billNoList) {
        MPJLambdaWrapper<ErpBudgetDetailEntity> queryWrapper = new MPJLambdaWrapper<ErpBudgetDetailEntity>()
                .selectAll(ErpBudgetDetailEntity.class)
                .selectAs(ErpBudgetItemEntity::getItemName, ErpBudgetDetailEntity::getBudgetItemName)
                .innerJoin(ErpBudgetItemEntity.class, ErpBudgetItemEntity::getItemId, ErpBudgetDetailEntity::getBudgetItemId);
        queryWrapper.in(ErpBudgetDetailEntity::getBillNo, billNoList);
        return detailMapper.selectList(queryWrapper);
    }
}
